// 类: 类的组成: 构造方法、属性(实例属性，原型属性、静态方法)，方法(实例的方法，原型方法，静态方法) 访问器， 静态相关的配置
class Circle {
    // 给这个类来声明属性
    public x:number
    public y:number
    public fn: ()=>void
    // 构造器--接收两个参数
    constructor(x:number,y:number = 200){ // 函数
        this.x = x
        this.y = y
        this.fn = ()=>{}
    }
}

new Circle(100,100)

// public 就是关键字的意思--公开属性，类的实例在外部和内部都可以访问这个属性，继承的子类也可以访问
// protected (我自己能访问，儿子能访问，外部无法访问)
// private(私有的，只有自己能访问)
// readonly 在初始化玩过后的时候，不能修改
// 原型方法就是每一个实例共享的方法
// static 我们也可以创建类的静态成员，这些属性存在于类本身上面而不是类的实例上


let circle = new Circle(100,100)
console.log('circle',circle.x);

class Animal {
    // 方式1
    // public name!:string  // 叹号表示 这个属性必须存在
    // constructor(name:string){

    // 方式2
    constructor(public name:string, public money:number){
        this.name = name
        this.money = money
    }
    // 原型方法
    changeMoney(value:number){
        this.money = value
        console.log('value',value)
    }

    // 原型属性 需要通过访问器来实现
    get aliasName(){
        return '$' + this.name
    }
    set aliasName(name:string){
        this.name = name
    }
    // static 是可以被子类继承的
    static a = 1
    static getA(){
        return this.a
    }
}

class Cat extends Animal {
    constructor(name:string, public age:number, public money:number){ // 初始化实例的属性和方法。当通过 new ClassName() 创建类的实例时，会自动调用 constructor。
        // 在继承中调用父类构造函数
        // 如果子类继承父类，必须在子类的 constructor 中先调用 super()，才能使用 this。这是为了确保父类的初始化逻辑先执行。  •  传递参数给父类
        // 通过 super(args) 将子类的参数传递给父类的构造函数。
        super(name,13) // 等于 Animal.call(this)   ----在继承中调用父类构造函数
        this.age = age
        this.money = money
    }
}

const tom = new Cat('tom',30,20)
tom.changeMoney(16)
console.log(Cat.a);

const fn:(a:string,b:string) => void  = function (a,b) {
    console.log('b',b);
    
}

fn('1','2')


class Singleton{
    //自己本身创造一个实例，后续一直用这个，不产生多个
    static instance = new Singleton();
    private constructor(){

    }
    static getInstance(){
        return this.instance
    }
}

let instance = Singleton.getInstance()
export {}